from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

from elastic_sys import Translater
from elastic_sys.elastic.elastic_manager import get_entity, get_entity_list, get_related_entity_list
from elastic_sys.elastic.search_manager import get_search_result, es, get_search_suggest, \
    get_search_counts, buckets_search
from elastic_sys.elastic.entity_definer import get_entity_enum_by_type_name, EntityEnum
from utils.response_utils import build_response, method_disallowed_response
import json
translater = Translater.YouDaoTranslator()
@csrf_exempt
def response_get_entity(request, entity_type_name, entity_id):
    if request.method != 'GET':
        return method_disallowed_response(request.method, 'GET')

    entity_enum = get_entity_enum_by_type_name(entity_type_name)
    if entity_enum is None:
        return build_response(errno=2001, msg=f"实体类型{entity_type_name}不存在")

    entity = get_entity(entity_enum, entity_id)
    if entity is None:
        return build_response(errno=2002, msg=f"实体{entity_enum.name} {entity_id}不存在")

    return build_response({
        entity_enum.name: entity
    }, msg="获取成功")


@csrf_exempt
def response_get_entity_list(request, entity_type_name):
    if request.method not in ['GET', 'POST']:
        return method_disallowed_response(request.method, 'GET', 'POST')

    entity_enum = get_entity_enum_by_type_name(entity_type_name)
    if entity_enum is None:
        return build_response(errno=2001, msg=f"实体类型{entity_type_name}不存在")

    dict_type = request.GET.get('dict_type', False)
    json_data = json.loads(request.body)
    entity_ids = json_data.get('id_list')
    result = get_entity_list(entity_enum, entity_ids, dict_type=dict_type)
    return build_response({
        "result": result
    }, msg="获取成功")


@csrf_exempt
def response_related_entity_list(request, relation, entity_id):
    if request.method != 'GET':
        return method_disallowed_response(request.method, 'GET')

    if relation == 'get_papers_by_authorships':
        result = get_related_entity_list(EntityEnum.paper, "authorships.author.id", entity_id, size=100)

    elif relation == 'get_papers_by_primary_location':
        result = get_related_entity_list(EntityEnum.paper, "primary_location.source.id", entity_id, size=100)

    elif relation == 'get_scholars_by_last_known_institution':
        result = get_related_entity_list(EntityEnum.scholar, "last_known_institution.id", entity_id, size=100)

    elif relation == 'get_papers_by_concepts':
        result = get_related_entity_list(EntityEnum.paper, "concepts.id", entity_id, size=20)

    elif relation == 'get_scholars_by_x_concepts':
        result = get_related_entity_list(EntityEnum.scholar, "x_concepts.id", entity_id, size=20)

    elif relation == 'get_venues_by_x_concepts':
        result = get_related_entity_list(EntityEnum.venue, "x_concepts.id", entity_id, size=20)

    elif relation == 'get_orgs_by_x_concepts':
        result = get_related_entity_list(EntityEnum.org, "x_concepts.id", entity_id, size=20)

    else:
        return build_response(errno=2001, msg=f"关系{relation}不存在")

    return build_response({
        "results": result
    }, msg="获取成功")


@csrf_exempt
def response_get_search_suggest(request):
    keyword = request.GET.get('keyword', None)
    target = request.GET.get('target', None)
    if is_legal_target(target):
        target = target + '_suggest'
        suggest = get_search_suggest(target, keyword)
        return JsonResponse({
            "errno": 1,
            "msg": "获取成功",
            "suggestions": suggest
        })
    else:
        return build_response(errno=2001, msg="非法的target")


def is_legal_target(target):
    if target is None:
        return False
    return target == 'paper' or target == 'scholar' or target == 'venue' or target == 'org' or target == 'concept'


def is_legal_agg(agg):
    if agg is None:
        return True
    for s in agg:
        if not (s.startswith('type_') or s.startswith('concepts_') or s.startswith('venue_') or s.startswith('level_')):
            return False
    return True
    print(result['docs'])


def is_legal_field(field):
    if field is None:
        return False
    if not (field == 'concepts' or field == 'venue' or field == 'type' or field == 'level'):
        return False
    else:
        return True


def is_legal_sort_key(sort_key, target):
    if not sort_key:
        return True
    if target == 'paper':
        return sort_key == 'publication_date' or sort_key == 'cited_by_count'
    else:
        return sort_key == 'works_count' or sort_key == 'cited_by_count' or sort_key == 'h_index' or sort_key == 'i10_index' or sort_key == '2yr_mean_citedness'


def is_all_chinese(s):
    for _char in s:
        if _char == ' ':
            continue
        if not '\u4e00' <= _char <= '\u9fa5':
            return False
    return True


@csrf_exempt
def response_search(request):
    data = json.loads(request.body) if request.body else {}
    keyword = request.GET.get('keyword', None)
    target = request.GET.get('target', None)
    sort_key = request.GET.get('sort_key', None)
    page_no = int(request.GET.get('page', 1))  # 1 - 500
    agg = data.get('agg', None)
    res_size = 10
    if keyword is None:
        return build_response(errno=2001, msg="缺少参数keyword")
    elif not is_legal_target(target):
        return build_response(errno=2002, msg="非法的target")
    elif page_no * res_size >= 10000:
        return build_response(errno=2003, msg="页码越界")
    elif not is_legal_sort_key(sort_key, target):
        return build_response(errno=2004, msg="非法的排序规则" + sort_key)
    res_from = (page_no - 1) * res_size
    paper_data = {}
    scholar_data = {}
    venue_data = {}
    org_data = {}
    concept_data = {}
    if is_all_chinese(keyword):
        keyword += " " + translater.translate(keyword, "zh2en")[0]
        print(keyword)
    if not sort_key:
        sort_key = None
    if target == 'paper':
        paper_data = get_search_result(target, res_from, res_size, keyword, agg=agg, sort_key=sort_key)
    elif target == 'scholar':
        scholar_data = get_search_result(target, res_from, res_size, keyword, sort_key=sort_key)
    elif target == 'org':
        org_data = get_search_result(target, res_from, res_size, keyword, agg=agg, sort_key=sort_key)
    elif target == 'venue':
        venue_data = get_search_result(target, res_from, res_size, keyword, agg=agg, sort_key=sort_key)
    elif target == 'concept':
        concept_data = get_search_result(target, res_from, res_size, keyword, agg=agg, sort_key=sort_key)

    summary = get_search_counts(keyword, agg)
    return JsonResponse({
        "errno": 1,
        "msg": "搜索成功",
        "summary": summary,
        "paper_data": paper_data,
        "scholar_data": scholar_data,
        "venue_data": venue_data,
        "org_data": org_data,
        "concept_data": concept_data
    })
    # if 'docs' in result:
    #     for doc in result['docs']:
    #         if doc['found']:  # 检查文档是否存在
    #             doc_id = doc['_id']
    #             doc_source = doc['_source']
    #             print(f"Document ID: {doc_id}")
    #             print(f"Document Source: {doc_source}")
    #         else:
    #             print("Document not found")
    print(result['docs', '_source'])


@csrf_exempt
def get_buckets_search(request):
    keyword = request.GET.get('keyword', None)
    target = request.GET.get('target', None)
    field = request.GET.get('field')
    if keyword is None:
        return build_response(errno=2001, msg="缺少参数keyword")
    elif not is_legal_target(target):
        return build_response(errno=2002, msg="非法的target")
    elif not is_legal_field(field):
        return build_response(errno=2005, msg="错误的聚合字段")
    return JsonResponse({
        "errno": 1,
        "msg": "搜索成功",
        "buckets": buckets_search(target, field, keyword)
    })


@csrf_exempt
def get_entity_statistics(request):
    if request.method != 'GET':
        return method_disallowed_response(request.method, 'GET')
    # entity_enum = get_entity_enum_by_type_name(entity_type_name)
    # if entity_enum is None:
    #     return build_response(errno=2001, msg=f"实体类型{entity_type_name}不存在")
    count_paper = es.count(index='paper')
    count_papers = count_paper['count']
    count_scholar = es.count(index='scholar')
    count_scholars = count_scholar['count']
    count_venue = es.count(index='venue')
    count_venues = count_venue['count']
    count_org = es.count(index='org')
    count_orgs = count_org['count']
    count_concept = es.count(index="concept")
    count_concepts = count_concept['count']
    with open('data.json') as json_file:
        data = json.load(json_file)
        result = data['concept_statistics']['cited_by_count']
        sorted_result = sorted(result, key=lambda x: float(x['_source']['summary_stats']['2yr_mean_citedness']),
                               reverse=True)
        sorted_source = [item['_source'] for item in sorted_result]
        time_result = data['time_statistics']
    return build_response({
        "sum_statistics": {
            "paper": count_papers,
            "scholar": count_scholars,
            "venue": count_venues,
            "org": count_orgs,
            "concept": count_concepts
        },
        "concept_statistics": sorted_source,
        "time_statistics": time_result
    }, msg="获取成功")
